package com.ant.storage.service.impl;

import cn.hutool.core.date.DateUtil;
import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.ant.storage.dto.HouseSettlementDto;
import com.ant.storage.handler.AntException;
import com.ant.storage.mapper.HouseSettlementMapper;
import com.ant.storage.mapper.InvoiceInfoMapper;
import com.ant.storage.pojo.*;
import com.ant.storage.service.*;
import com.ant.storage.utils.DateFormat;
import com.ant.storage.utils.RandomUtil;
import com.ant.storage.wechat.WeChatUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taobao.api.ApiException;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author melon
 * @since 2023-11-13
 */
@Service
public class HouseSettlementServiceImpl extends ServiceImpl<HouseSettlementMapper, HouseSettlement> implements IHouseSettlementService {

    @Autowired
    public ServletContext servletContext;

    @Resource
    private IAuditListService auditListService;

    @Resource
    private IHouseLeaseService houseLeaseService;

    @Resource
    private IHouseAccountService accountService;

    @Resource
    private IInvoiceInfoService infoService;

    @Resource
    private InvoiceInfoMapper infoMapper;

    @Resource
    private IPurchaserRecordImgService imgService;

    @Autowired
    public IApprovalMsgService approvalMsgService;
    @Autowired
    IErrMsgService errMsgService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo houseSettlemenSave(HouseSettlementDto dto) throws Exception {
        synchronized (this) {
            if (dto.getContractId() == null) {
                throw new AntException(ResultCode.NOT_FOUND.getResultCode(), "请选择合同");
            }
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            dto.setParentId(dto.getContractId());
            dto.setCreateBy(userInfo.getNameId().toString());
            dto.setCreateTime(new Date());
            HouseLease houseLease = houseLeaseService.getOne(new QueryWrapper<HouseLease>().eq("id",
                    dto.getContractId()));
            if (houseLease == null) {
                throw new AntException(ResultCode.NOT_FOUND.getResultCode(), "合同不存在");
            }
            if (houseLease.getContractStatus() == 0) {
                throw new AntException(ResultCode.NOT_FOUND.getResultCode(), "合同到期");
            }
            HouseSettlement settlement = this.baseMapper.selectMaxOne(dto.getContractId());
            HouseAccount one = accountService.getOne(new QueryWrapper<HouseAccount>().eq("id",
                    dto.getHouseAccountId()));
            if (one == null) {
                throw new AntException(ResultCode.NOT_FOUND);
            }
            Date date = null;
            if (settlement == null || settlement.getEndTime() == null) {
                Date dates = new Date();
                dto.setStartTime(dates);
                date = DateFormat.addOneMonth(DateUtil.formatDate(dates), dto.getPayment());
                dto.setEndTime(date);
            } else {
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                String dateString = formatter.format(settlement.getEndTime());
                date = DateFormat.addOneMonth(dateString, dto.getPayment());
                dto.setStartTime(settlement.getEndTime());
                dto.setEndTime(date);
            }
            this.baseMapper.insert(dto);
            houseLeaseService.update(new UpdateWrapper<HouseLease>().set("fee_due", date).eq("id",
                    dto.getContractId()));
            InvoiceInfo info = new InvoiceInfo();
            info.setHouseLeaseId(dto.getContractId());
            info.setInvoiceType(dto.getInvoiceType());
            info.setInvoiceNumber("QK" + RandomUtil.getOrderNumbers(infoMapper.selectLastID()));
            info.setInvoicePrice(dto.getAmount());
            info.setInvoiceName(houseLease.getContractName() + "续费申请");
            info.setReimbursementType(dto.getReimbursementTypeId());


            info.setAnnex(houseLease.getContractAnnex());
            info.setCityId(houseLease.getCityId());
            info.setDepId(houseLease.getCompanyId());
            info.setAccountName(one.getAccountName());
            info.setAccountBank(one.getAccountBank());
            info.setAccountNumber(one.getAccountNumber());
            info.setPaymentMethod(dto.getPaymentMonth());
            info.setInvoiceNotes(dto.getNotes());
            info.setAccountUrgency(dto.getAccountUrgency());
            info.setCreateBy(userInfo.getNameId().toString());
            info.setCreationTime(new Date());
            infoService.save(info);

            if (dto.getIsApproved() == 1) {
                // 判断是否为空
                if (dto.getApproval().size() == 0 || dto.getApproval() == null) {
                    throw new AntException("请选择审批人员");
                }
                AuditList auditList = new AuditList();
                auditList.setParentId(info.getId());
                auditList.setProcessType(dto.getInvoiceType() == 1 ? "funds" : "rent_review");
                auditList.setCreationTime(new Date());
                auditList.setName(userInfo.getNameId().toString());
                // 添加审核记录
                for (String str : dto.getApproval()) {
                    auditList.setNameId(str);
                    auditList.setTypes("1");
                    auditListService.save(auditList);
                }
                if (dto.getNotify().size() == 0 || dto.getNotify() == null) {
                    throw new AntException("请选择抄送人");
                }
                for (String str2 : dto.getNotify()) {
                    auditList.setNameId(str2);
                    auditList.setTypes("2");
                    auditListService.save(auditList);
                }
                if (houseLease == null) {
                    throw new AntException(ResultCode.NOT_FOUND);
                }

                info.setApproval(dto.getApproval());
                info.setNotify(dto.getNotify());
                info.setWeChat(userInfo.getWeChat());
                info.setReimbursementTypeText("房租费续费");

                info.setUserName(userInfo.getUserName());
                List<ReimburseDetail> list = new ArrayList<>();
                ReimburseDetail detail = new ReimburseDetail();
                detail.setProjectName(userInfo.getUserName());
                detail.setProjectAmount("1");
                detail.setProjectUnit("间");
                detail.setProjectPrice(dto.getAmount());
                list.add(detail);
                info.setDetailList(list);
                String str = WeChatUtils.launchWeChatData(info);

                ApprovalMsg msg=new ApprovalMsg();
                msg.setParentId(info.getId()); // 申请列表id;
                msg.setApprovalType(dto.getInvoiceType() == 1 ? "funds" : "rent_review");
                msg.setApprovalUser(userInfo.getUserName());
                msg.setApprovalUserId(userInfo.getNameId());
                msg.setSpNo(str);
                msg.setCreationTime(new Date());
                approvalMsgService.save(msg);

                this.update(new UpdateWrapper<HouseSettlement>().set(
                        "process_instance_id", str)
                        .set("audits_status", 0)
                        .eq("id", dto.getId()));
                infoService.update(new UpdateWrapper<InvoiceInfo>().set(
                        "process_instance_id", str)
                        .eq("id", info.getId()));
                return ResultVo.success("操作成功");

//                // 发起钉钉审批
//                // 通过 getUserId()
//                FundsDto ding = new FundsDto();
//                ding.setOriginator_userid(userInfo.getDingTalk());
//                ding.setDeptId(userInfo.getDepId());
//                ding.setId(dto.getId());
//                ding.setApprover_userid(dto.getApproval());
//                ding.setCc_userId(dto.getNotify());
//                ding.setCity(houseLease.getCityId().toString());
//                ding.setDate(DateFormat.getCurrentDates());
//                ding.setUrgency(dto.getAccountUrgency());
//                ding.setAmount(dto.getAmount().toString());
//                ding.setPicture(getPicture(dto.getContractId())); // 图片
//                ding.setCompanyName(userInfo.getDepName());
//                ding.setReason(dto.getNotes());
//                ding.setProjectDtoList(null);
//                ding.setAccess_token(DingDingUtil.obtainToken());
//                try {
//                    String process_instance_id = DingDingUtil.OldRequestFunds(ding);
//                    ErrMsg msg = new ErrMsg();
//                    msg.setErrCode("201");
//                    msg.setErrValue(process_instance_id + JSON.toJSONString(dto));
//                    errMsgService.save(msg);
//                    if (process_instance_id.equals("201")) {
//                        throw new AntException(ResultCode.FAILURE.getResultCode(), "钉钉提交失败");
//                    } else {
//                        this.update(new UpdateWrapper<HouseSettlement>().set(
//                                "process_instance_id", process_instance_id)
//                                .set("audits_status", 0)
//                                .eq("id", dto.getId()));
//                        infoService.update(new UpdateWrapper<InvoiceInfo>().set(
//                                "process_instance_id", process_instance_id)
//                                .eq("id", info.getId()));
//                        return ResultVo.success("操作成功");
//                    }
//
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
            }
            return ResultVo.success("操作成功");
        }
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public String addWeChatData(InvoiceInfo dto) throws AntException {
        InvoiceInfo info = new InvoiceInfo();
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        info.setWeChat(userInfo.getWeChat());
        info.setUserName(userInfo.getUserName());
        info.setReimbursementTypeText("房租费续费");
        info.setApproval(dto.getApproval());
        info.setNotify(dto.getNotify());
        List<ReimburseDetail> list = new ArrayList<>();
        ReimburseDetail detail = new ReimburseDetail();
        detail.setProjectName(userInfo.getUserName());
        detail.setProjectAmount("1");
        detail.setProjectUnit("间");
        detail.setProjectPrice(dto.getInvoicePrice());
        list.add(detail);
        info.setDetailList(list);
        String str = WeChatUtils.launchWeChatData(info);
        return str;
    }

    public List<String> getPicture(Integer contractId) throws ApiException {
        HouseLease lease = houseLeaseService.getOne(new QueryWrapper<HouseLease>().eq("id", contractId));
        if (lease != null && StringUtils.isNotEmpty(lease.getContractAnnex())) {
            List<Integer> list = Arrays.asList(lease.getContractAnnex().split(",")).
                    stream().map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
            List<PurchaserRecordImg> imgList = imgService.list(new QueryWrapper<PurchaserRecordImg>()
                    .in("id", list));
            return imgList.stream().map(p -> p.getUrl()).collect(Collectors.toList());
        }
        return null;
    }
}
